package com.zbkj.service.manager;

import com.zbkj.dal.entity.fund.UserFundAccount;
import com.zbkj.dal.entity.system.SystemUserLevel;
import com.zbkj.dal.entity.user.User;
import com.zbkj.dal.entity.user.UserQuotaAccount;
import com.zbkj.service.model.dto.FundUpdateDTO;
import com.zbkj.service.model.dto.SaveUserBalanceRecordDTO;
import com.zbkj.service.model.dto.UseAvailableResultDTO;
import com.zbkj.service.model.front.vo.fund.CrabRoeAccountVO;
import com.zbkj.service.model.front.vo.fund.UserQuotaVO;
import org.apache.commons.lang3.tuple.Pair;

import java.math.BigDecimal;

public interface FundManager {

    /**
     * 用户雅识账户信息
     *
     * @param userId userId
     * @return {@link CrabRoeAccountVO}
     */
    CrabRoeAccountVO userCrabRoeAccount(Integer userId);

    /**
     * 查询用户资金账户
     *
     * @param userId      userId
     * @param accountType accountType
     * @return {@link UserFundAccount}
     */
    UserFundAccount findByIdAndAccountType(Integer userId, String accountType);

    /**
     * 添加雅识请求
     *
     * @param fundUpdateDTO fundUpdateDTO
     */
    void addCrabRoeApply(FundUpdateDTO fundUpdateDTO);

    /**
     * 添加雅识申请取消
     *
     * @param bizOrderNo 业务单号
     */
    void addCrabRoeApplyCancel(String bizOrderNo);

    /**
     * 添加雅识确认
     *
     * @param bizOrderNo 业务单号
     */
    void addCrabRoeConfirm(String bizOrderNo);

    /**
     * 查询用户额度账户信息
     *
     * @param userId      userId
     * @param accountType 账户类型
     * @return {@link UserFundAccount}
     */
    Pair<User, UserFundAccount> queryAndCheckFundAccount(Integer userId, String accountType);

    /**
     * 资金账户
     *
     * @param userId      用户 ID
     * @param accountType 账户类型
     * @return {@link UserFundAccount}
     */
    UserFundAccount fundAccount(Integer userId, String accountType);

    /**
     * 添加可用金额
     *
     * @param userId          用户Id
     * @param amount          金额
     * @param fundAccountType 资金账户类型
     * @return {@link UserFundAccount}
     */
    UserFundAccount addAvailableAmount(Integer userId, BigDecimal amount, String fundAccountType);

    /**
     * 添加可用金额
     *
     * @param user            用户
     * @param amount          金额
     * @param fundAccountType 资金账户类型
     * @return {@link UserFundAccount}
     */
    UserFundAccount addAvailableAmount(User user, BigDecimal amount, String fundAccountType);

    /**
     * 减少可用金额
     *
     * @param userId          userId
     * @param amount          金额
     * @param fundAccountType 资金账户类型
     * @return {@link UserFundAccount}
     */
    UserFundAccount minusAvailableAmount(Integer userId, BigDecimal amount, String fundAccountType);

    /**
     * 减少可用金额
     *
     * @param user            用户
     * @param amount          金额
     * @param fundAccountType 资金账户类型
     * @return {@link UserFundAccount}
     */
    UserFundAccount minusAvailableAmount(User user, BigDecimal amount, String fundAccountType);

    /**
     * 使用可用金额
     * 如果使用金额大于用户可用金额，则使用可用金额，否则使用指定金额
     *
     * @param user            用户
     * @param amount          金额
     * @param fundAccountType 资金账户类型
     * @return {@link UserFundAccount}
     */
    UseAvailableResultDTO useAvailableAmount(User user, BigDecimal amount, String fundAccountType);

    /**
     * 获取可用金额
     *
     * @param user            用户
     * @param amount          金额
     * @param fundAccountType 资金账户类型
     * @return {@link UserFundAccount}
     */
    UseAvailableResultDTO getAvailableAmount(User user, BigDecimal amount, String fundAccountType);

    UseAvailableResultDTO useAvailableAmountAndRecordForOrderCreate(User user, String bizOrderNo, BigDecimal amount,String image);

    void backAvailableAmountAndRecordForOrderCancel(User user, String bizOrderNo, BigDecimal amount,String image);

    /**
     * 保存用户余额记录
     *
     * @param saveUserBalanceRecordDTO {@link SaveUserBalanceRecordDTO}
     */
    void saveUserBalanceRecord(SaveUserBalanceRecordDTO saveUserBalanceRecordDTO);

}
